#ifdef KITSCHY_DEBUG_MEMORY 
#include "debug_memorymanager.h"
#endif

#ifdef WIN32
#include "windows.h"
#else
#include <sys/time.h>
#include <time.h>
#endif
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "stdarg.h"
#include "math.h"

#include "BList.h"

#include "symbol.h"
#include "sort.h"
#include "ontology.h"
#include "featureterm.h"
#include "FTKBase.h"
#include "AUfeatureterm.h"
#include "FT_refinement.h"
#include "FT_generalization.h"

#include "Planning.h"
#include "SearchBasedPlanning.h"
#include "SNLP.h"




#ifndef WIN32
struct timeval init_tick_count_value;

void setupTickCount()
{
	gettimeofday(&init_tick_count_value, NULL);
}

long GetTickCount()
{
	struct timeval now;
	gettimeofday(&now, NULL);
	struct timeval diff;
	diff.tv_sec = now.tv_sec - init_tick_count_value.tv_sec;
	diff.tv_usec = now.tv_usec - init_tick_count_value.tv_usec;
	if (diff.tv_usec < 0)
	{
		diff.tv_sec--;
		diff.tv_usec+=1000000;
	}
	return diff.tv_sec*1000 + diff.tv_usec/1000;
}
#endif



int main(void)
{
	int t_start,t_end;

#ifndef WIN32
	setupTickCount();
#endif

	Ontology *o=new Ontology();
	FTKBase *domain_model=new FTKBase(o);
	FTKBase *problem_base=new FTKBase(o);
	problem_base->uses(domain_model);

	domain_model->create_boolean_objects(o);

	printf("Stats 0: %i %i\n",Symbol::stats_nSymbols(),Symbol::stats_nSymbolReferences());

	{

		domain_model->ImportNOOS("planning-ontology.noos",o);

		initPlanning(o);
/*
		domain_model->ImportNOOS("gripper-strips-ontology.noos",o);
		domain_model->ImportNOOS("gripper-strips-dm.noos",o);
		problem_base->ImportNOOS("gripper-strips-problems.noos",o);
*/

		domain_model->ImportNOOS("gripper-adl-ontology.noos",o);
		domain_model->ImportNOOS("gripper-adl-dm.noos",o);
		problem_base->ImportNOOS("gripper-adl-problems.noos",o);

		printf("Stats 1: %i %i\n",Symbol::stats_nSymbols(),Symbol::stats_nSymbolReferences());

		printf("There are %i undefined terms.\n",domain_model->get_n_undefined_terms());
		domain_model->print_undefined_terms();
		printf("There are %i undefined terms.\n",problem_base->get_n_undefined_terms());
		problem_base->print_undefined_terms();

		t_start=GetTickCount();

		{
			// Print operators
			List<FeatureTerm> *operators = domain_model->SearchFT(o->get_sort("operator"));
			List<FeatureTerm> *problems = problem_base->SearchFT(o->get_sort("planning-problem"));
			FeatureTerm *f;

			printf("%i operators:\n",operators->Length());
			operators->Rewind();
			while(operators->Iterate(f)) {
				char *s = f->toStringNOOS(domain_model);
				printf("%s\n",s);
				delete []s;
			} // while 

			printf("%i problems:\n",problems->Length());
			problems->Rewind();
			while(problems->Iterate(f)) {
				char *s = f->toStringNOOS(domain_model);
				printf("%s\n",s);
				delete []s;
			} // while 

			if (problems->Length()>0) {
				FeatureTerm *problem = problems->operator [](0);
				List<FeatureTerm> *objects;

				{
					FeatureTerm *f = problem->featureValueQuick("objects");
					if (f->isSet()) {
						objects = f->set_values();
					} else {
						objects = new List<FeatureTerm>;
						objects->Add(new FeatureTerm(f));
					} // if
				}

				printf("%i objects:\n",objects->Length());
				objects->Rewind();
				while(objects->Iterate(f)) {
					char *s = f->toStringNOOS(domain_model);
					printf("%s\n",s);
					delete []s;
				} // while 

//				List<FeatureTerm> *plan = IDSearchBasedPlan(objects,problem->featureValueQuick("initial-state"),problem->featureValueQuick("goal"),domain_model,o);
				List<FeatureTerm> *plan = HSearchBasedPlan(objects,problem->featureValueQuick("initial-state"),problem->featureValueQuick("goal"),domain_model,o);
//				List<FeatureTerm> *plan = SNLP_dfs(problem->featureValueQuick("initial-state"),problem->featureValueQuick("goal"),domain_model,o);

				if (plan!=0) {
					printf("Plan has %i steps:\n",plan->Length());
					plan->Rewind();
					while(plan->Iterate(f)) {
						printOperatorNice(f,domain_model);
					} // while 

					delete plan;
				} // if

				delete objects;
			} // if 


			operators->ExtractAll();
			delete operators;

			problems->ExtractAll();
			delete problems;
		}

		t_end=GetTickCount();

		printf("Time taken: %i\n",t_end-t_start);

		printf("Stats 2: %i %i\n",Symbol::stats_nSymbols(),Symbol::stats_nSymbolReferences());
	}

	delete problem_base;
	delete domain_model;

	printf("Stats 3: %i %i\n",Symbol::stats_nSymbols(),Symbol::stats_nSymbolReferences());

	delete o;

	printf("Stats 4: %i %i\n",Symbol::stats_nSymbols(),Symbol::stats_nSymbolReferences());
	Symbol::stats_printSymbolStats();

	Symbol::reset();

	return 0;
} /* main */ 




